package org.ewancle.springboothivehdfs.controller;

import lombok.extern.slf4j.Slf4j;
import org.ewancle.springboothivehdfs.service.HiveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Slf4j
@RestController
@RequestMapping("/api/hive")
public class HiveController {

    private final HiveService hiveService;

    @Autowired
    public HiveController(HiveService hiveService) {
        this.hiveService = hiveService;
    }

    @PostMapping("/query")
    public ResponseEntity<?> executeQuery(@RequestBody Map<String, String> request) {
        String sql = request.get("sql");
        if (sql == null || sql.isEmpty()) {
            Map<String, Object> error = new HashMap<>();
            error.put("error", "SQL is required");
            return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
        }

        try {
            List<Map<String, Object>> result = hiveService.executeQuery(sql);
            Map<String, Object> response = new HashMap<>();
            response.put("data", result);
            response.put("rowCount", result.size());

            return ResponseEntity.ok(response);
        } catch (SQLException e) {
            log.error("Query execution failed: {}", sql, e);
            Map<String, Object> error = new HashMap<>();
            error.put("error", e.getMessage());
            return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @PostMapping("/query-async")
    public CompletableFuture<ResponseEntity<?>> executeQueryAsync(@RequestBody Map<String, String> request) {
        String sql = request.get("sql");
        if (sql == null || sql.isEmpty()) {
            Map<String, Object> error = new HashMap<>();
            error.put("error", "SQL is required");
            return CompletableFuture.completedFuture(
                    new ResponseEntity<>(error, HttpStatus.BAD_REQUEST));
        }

        /*return hiveService.executeQueryAsync(sql)
                .thenApply(result -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("data", result);
                    response.put("rowCount", result.size());

                    return ResponseEntity.ok(response);
                })
                .exceptionally(e -> {
                    log.error("Async query execution failed: {}", sql, e);
                    Map<String, Object> error = new HashMap<>();
                    error.put("error", e.getMessage());
                    return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
                });*/
        return null;
    }

    @PostMapping("/update")
    public ResponseEntity<?> executeUpdate(@RequestBody Map<String, String> request) {
        String sql = request.get("sql");
        if (sql == null || sql.isEmpty()) {
            Map<String, Object> error = new HashMap<>();
            error.put("error", "SQL is required");
            return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
        }

        try {
            int rowsAffected = hiveService.executeUpdate(sql);
            Map<String, Object> response = new HashMap<>();
            response.put("rowsAffected", rowsAffected);

            return ResponseEntity.ok(response);
        } catch (SQLException e) {
            log.error("Update execution failed: {}", sql, e);
            Map<String, Object> error = new HashMap<>();
            error.put("error", e.getMessage());
            return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @PostMapping("/create-database")
    public ResponseEntity<Map<String, Object>> createDatabase(
            @RequestParam String database,
            @RequestParam(defaultValue = "true") boolean ifNotExists) {

        Map<String, Object> response = new HashMap<>();
        boolean result = hiveService.createDatabase(database, ifNotExists);
        response.put("success", result);
        response.put("database", database);

        return new ResponseEntity<>(response, result ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @PostMapping("/create-table")
    public ResponseEntity<Map<String, Object>> createTable(@RequestBody Map<String, String> request) {
        String sql = request.get("sql");
        if (sql == null || sql.isEmpty()) {
            Map<String, Object> error = new HashMap<>();
            error.put("error", "SQL is required");
            return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
        }

        Map<String, Object> response = new HashMap<>();
        boolean result = hiveService.createTable(sql);
        response.put("success", result);

        return new ResponseEntity<>(response, result ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @DeleteMapping("/drop-table")
    public ResponseEntity<Map<String, Object>> dropTable(
            @RequestParam String database,
            @RequestParam String tableName,
            @RequestParam(defaultValue = "true") boolean ifExists) {

        Map<String, Object> response = new HashMap<>();
        boolean result = hiveService.dropTable(database, tableName, ifExists);
        response.put("success", result);
        response.put("database", database);
        response.put("table", tableName);

        return new ResponseEntity<>(response, result ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @GetMapping("/describe-table")
    public ResponseEntity<?> describeTable(
            @RequestParam String database,
            @RequestParam String tableName) {

        try {
            List<Map<String, Object>> columns = hiveService.describeTable(database, tableName);
            Map<String, Object> response = new HashMap<>();
            response.put("database", database);
            response.put("table", tableName);
            response.put("columns", columns);

            return ResponseEntity.ok(response);
        } catch (SQLException e) {
            log.error("Describe table failed: {}.{}", database, tableName, e);
            Map<String, Object> error = new HashMap<>();
            error.put("error", e.getMessage());
            return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @PostMapping("/insert")
    public ResponseEntity<Map<String, Object>> insertData(
            @RequestParam String database,
            @RequestParam String tableName,
            @RequestBody Map<String, Object> data) {

        Map<String, Object> response = new HashMap<>();
        boolean result = hiveService.insertData(database, tableName, data);
        response.put("success", result);
        response.put("database", database);
        response.put("table", tableName);

        return new ResponseEntity<>(response, result ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @PostMapping("/batch-insert")
    public ResponseEntity<Map<String, Object>> batchInsertData(
            @RequestParam String database,
            @RequestParam String tableName,
            @RequestBody List<Map<String, Object>> dataList) {

        Map<String, Object> response = new HashMap<>();
        boolean result = hiveService.batchInsertData(database, tableName, dataList);
        response.put("success", result);
        response.put("database", database);
        response.put("table", tableName);
        response.put("recordCount", dataList.size());

        return new ResponseEntity<>(response, result ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @PutMapping("/update")
    public ResponseEntity<Map<String, Object>> updateData(
            @RequestParam String database,
            @RequestParam String tableName,
            @RequestParam String condition,
            @RequestBody Map<String, Object> data) {

        Map<String, Object> response = new HashMap<>();
        boolean result = hiveService.updateData(database, tableName, data, condition);
        response.put("success", result);
        response.put("database", database);
        response.put("table", tableName);

        return new ResponseEntity<>(response, result ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @DeleteMapping("/delete")
    public ResponseEntity<Map<String, Object>> deleteData(
            @RequestParam String database,
            @RequestParam String tableName,
            @RequestParam String condition) {

        Map<String, Object> response = new HashMap<>();
        boolean result = hiveService.deleteData(database, tableName, condition);
        response.put("success", result);
        response.put("database", database);
        response.put("table", tableName);

        return new ResponseEntity<>(response, result ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
